//***************************************************************
//* Name:      mCanvas.h
//* Author:    Riku Maikola (rpm@ac-mapa.org)
//* Created:   2012-12-19
//* Copyright: Riku Maikola (rpm.ac-mapa.org)
//* License:
//**************************************************************/

#ifndef mCanvas_H
#define mCanvas_H

//VBO numbers***************************************//
enum{
        MAXVBO = 300,
        startToolPos = 400,
        PAVBO = 450,          //select area Area
        SIMVBO,               //SIM VBO *** path
        GRIDVBO,              //SIM VBO *** path
        VBOCOUNT
};

#include <GL/glew.h>
#include <wx/glcanvas.h>
#include <vector>
#include <fstream>
#include "mPoint.h"
#include "vmath.h"
#include "vertex.h"

class VBO
{
public:
    bool show = false;
    std::string filename="";
    int TimeOfUpdate = 0;

    GLuint type = 0;          //GL_TRIANGLES...etc
    GLuint size = 0;          //Sizeof vertex buffer

    uint shader = 0;          //
    bool world;
};


struct shader_program
{
    GLuint program;
    GLint move,view,proj;
};

class mCanvas : public wxGLCanvas
{
private:
    GLuint vbos[VBOCOUNT+1];                       //buffer names
    GLuint T[10];
    shader_program S[10];                   //shader programs

public:
    VBO vbo[VBOCOUNT+1];                           //VBO OBJECTS....

    vmath::mat4 proj_matrix;
    vmath::mat4 view_matrix;
    vmath::mat4 mv_matrix;

    vmath::vec3 center ;
    float rx,rz,scale=1;

    mPoint rightC = mP(1,0,0);
    mPoint upC = mP(0,1,0);
    mPoint eyeM = mP(0,0,1);


    int W,H;                                        //image size

    //************************//
    mCanvas(wxWindow * parent,wxWindowID id,const wxPoint & pos,const wxSize& size,long style=0,const wxString & name = _("GLCanvas"),int * attribList = 0,const wxPalette & palette = wxNullPalette) : wxGLCanvas(parent, id, pos, size, style, name, attribList, palette)
    {}
    ~mCanvas()
    {
        glDeleteBuffers(500, vbos);
    }

    void Init();                                                                        //
    //void Add(uint id,wxImage);
    void Shader(uint,const std::string vertex_shader,const std::string fragment_shader);

    void Update(GLuint,DrawBuffer * DB );
    void Render(uint,mPoint p=mP(0,0,0),bool renderID=false);

    //***********************//
    void ViewPort();
    void window(uint id , uint Sh,double height,double width);

    uint PICK(GLuint,int X,int Y);

    //***********//
    void LookDirection(double Hor,double Ver)
    {
         rz += Hor;
         rx += Ver;

         rightC.SetValue(1,0,0);
         upC.SetValue(0,1,0);
         eyeM.SetValue(0,0,1);

         eyeM.RotateX(rx);
         upC.RotateX(rx);
         rightC.RotateX(rx);

         eyeM.RotateXY(rz);
         upC.RotateXY(rz);
         rightC.RotateXY(rz);
    }

    //***********//
    void LookMove(double X,double Y)
    {
        center += vmath::vec3(  upC.x*Y , upC.y*Y, upC.z*Y  ) + vmath::vec3(  rightC.x*X , rightC.y*X, rightC.z*X  );
    }


    void LookAt()
    {
        view_matrix = vmath::lookat( center+(vmath::vec3(eyeM.x,eyeM.y,eyeM.z)*1000) , center , vmath::vec3(  upC.x , upC.y, upC.z ));
        view_matrix *= vmath::scale(scale);
    }
};
#endif
